package com.keyidea.jfxui.core.server.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通用工具类
 */
@Slf4j
public class CommonUtil {
    /**
     * 获取UUID字符串，长度32
     *
     * @return UUID字符串
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
    }

    /**
     * 加密输入的字符串
     *
     * @param str 字符串
     * @return 加密后的字符串
     */
    public static String encoderByMd5(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        String encodeStr = "";
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");

            //加密后的字符串
            encodeStr = Base64.getEncoder().encodeToString(md5.digest(str.getBytes(StandardCharsets.UTF_8)));
        } catch (Exception e) {
            log.error("encoderByMd5 error.", e);
        }
        return encodeStr;
    }

    /**
     * 判断用户密码是否正确
     * newpasswd 用户输入的密码
     * oldpasswd 正确密码
     */
    public static boolean checkpassword(String newpasswd, String oldpasswd) {
        return Objects.equals(encoderByMd5(newpasswd), oldpasswd);
    }

    /**
     * @param request
     * @Description 获取客户端真实ip
     */
//    public static String getIpAddr(HttpServletRequest request)
//    {
//        String ip = request.getHeader("x-forwarded-for");
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
//        {
//            ip = request.getHeader("Proxy-Client-IP");
//        }
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
//        {
//            ip = request.getHeader("WL-Proxy-Client-IP");
//        }
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
//        {
//            ip = request.getHeader("X-Real-IP");
//        }
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
//        {
//            ip = request.getRemoteAddr();
//        }
//        return ip;
//    }

    /**
     * 匹配是否为数字
     *
     * @param str 需要判断的数字字符串
     */
    public static boolean isNumeric(String str) {
        // 该正则表达式可以匹配所有的数字 包括负数
        Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
        String bigStr;
        try {
            bigStr = new BigDecimal(str).toString();
        } catch (Exception e) {
            return false;
        }

        Matcher isNum = pattern.matcher(bigStr);
        return isNum.matches();
    }

    /**
     * 字符串转换成List
     *
     * @param str   需要转换的字符串
     * @param split 分隔符
     * @return List
     */
    public static List<Integer> stringToList(String str, String split) {
        List<Integer> retList = new ArrayList<Integer>();
        if (StringUtils.isNotBlank(str)) {
            String[] strIdArr = StringUtils.split(str, split);
            for (String strId : strIdArr) {
                retList.add(Integer.valueOf(strId));
            }
        }
        return retList;
    }

    /**
     * 字符串转换成List 字符串
     *
     * @param str   需要转换的字符串
     * @param split 分隔符
     * @return List
     */
    public static List<String> stringToListStr(String str, String split) {
        List<String> retList = new ArrayList<>();
        if (StringUtils.isNotBlank(str)) {
            String[] strArr = StringUtils.split(str, split);
            Collections.addAll(retList, strArr);
        }
        return retList;
    }

//    /**
//     * 校验指定key下的响应数据是否存在
//     *
//     * @param mapKey 数据key
//     * @return true：存在 false：不存在
//     */
//    public static boolean checkReqBlockQueueMap(String mapKey)
//    {
//        try
//        {
//            BlockingQueue<Map<String, Object>> req_block_queue = new LinkedBlockingQueue<>();
//            MemStorage.REQ_BLOCK_QUEUE_MAP.put(mapKey, req_block_queue);
//            Map<String, Object> returnMap = req_block_queue.poll(10, TimeUnit.SECONDS);
//            if (null == returnMap)
//            {
//                return false;
//            }
//            else
//            {
//                String result = returnMap.get(mapKey).toString();
//                return !StringUtils.isBlank(result);
//            }
//        }
//        catch (Exception e)
//        {
//            return false;
//        }
//        finally
//        {
//            if (null != mapKey)
//            {
//                MemStorage.REQ_BLOCK_QUEUE_MAP.remove(mapKey);
//                log.info("清除消息[{}]", mapKey);
//            }
//        }
//
//    }

//    public static boolean parseAirInterfaceReqHead(byte[] msg, AirInterfaceReqHead airReqHead)
//    {
//        if (msg.length < 24)
//        {
//            log.error("msg length < 24, parse AirInterfaceReqHead failed!");
//            return false;
//        }
//
//        airReqHead.setChannelAssociated(ByteUtils.subBytes(msg, 1, 16));
//        airReqHead.setModemId(ByteUtils.getData(msg, 17, 4, Integer.class));
//        airReqHead.setSignaling(ByteUtils.getData(msg, 21, 1, Integer.class));
//        airReqHead.setMsgId(ByteUtils.getData(msg, 22, 1, Integer.class));
//        airReqHead.setRetryTimes(ByteUtils.getData(msg, 23, 1, Integer.class));
//
//        return true;
//    }
//
//    public static boolean parseAirInterfaceRspHead(byte[] msg, AirInterfaceRspHead airRspHead)
//    {
//        if (msg.length < 24)
//        {
//            log.error("msg length < 24, parse AirInterfaceReqHead failed!");
//            return false;
//        }
//
//        IoBuffer ioBuffer = IoBuffer.allocate(1).setAutoExpand(true);
//        // 协议簇
//        ioBuffer.put(airRspHead.getProtocolId());
//        // modemId TODO
//        //ioBuffer.put()
//
//        // 消息头
//        int messageNumber = new Random().nextInt(256);
//        //ioBuffer.put(ByteUtils.getUdpSinalingHead(rspHead.getModem().getModemStr(), 2, messageNumber));
//
//        //airRspHead.setProtocolId(ByteUtils.subBytes(msg, 1, 16));
//        airRspHead.setModemId(ByteUtils.getData(msg, 17, 4, Integer.class));
//        airRspHead.setSignaling(ByteUtils.getData(msg, 21, 1, Integer.class));
//        airRspHead.setMsgId(ByteUtils.getData(msg, 22, 1, Integer.class));
//        airRspHead.setRspCode(ByteUtils.getData(msg, 23, 1, Integer.class));
//
//        return true;
//    }


//    public static boolean parseCenterStationControlReqHead(byte[] msg, CenterStationControlReqHead cscReqHead)
//    {
//        if (msg.length < 8)
//        {
//            log.error("msg length < 8, parse parseCenterStationControlReqHead failed!");
//            return false;
//        }
//
//        cscReqHead.setSignaling(ByteUtils.getData(msg, 1, 1, Integer.class));
//        cscReqHead.setMsgId(ByteUtils.getData(msg, 2, 1, Integer.class));
//        cscReqHead.setDeviceType(ByteUtils.getData(msg, 3, 1, Integer.class));
//        cscReqHead.setDeviceId(ByteUtils.getData(msg, 4, 4, Integer.class));
//
//        return true;
//    }

    /**
     * 判断对象是否未Null
     *
     * @param o
     * @return
     */
    public static boolean ObjectIsNull(Object o) {
        if (null != o) {
            Class cla = o.getClass();
            Field[] declaredFields = cla.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                Object fieldVal = null;
                try {
                    fieldVal = field.get(o);
                    if (null != fieldVal) {
                        return false;
                    }
                } catch (IllegalAccessException e) {
                    log.error("Object is null examine process occur an error, reason is {}", e.getMessage(), e);
                }
            }
        }
        return true;
    }

    /**
     * @param type
     *     1-上行 2-下行
     * @param airProtocoBytes
     *
     * @return
     *
     * @throws Exception
     */
//    public static List<ParseResultEntity> pareseAirProtocolBytes(int type, byte[] airProtocoBytes) throws Exception
//    {
//        List<ParseResultEntity> result = new ArrayList<>();
//        if (null == airProtocoBytes || airProtocoBytes.length == 0)
//        {
//            throw new Exception("Data array is null or empty");
//        }
//
//        int protocolType = airProtocoBytes[0];
//        int sglCode = -1;
//        switch (protocolType)
//        {
//            case 1 -> {
//                sglCode = type == 1 ? airProtocoBytes[21] : airProtocoBytes[5];
//            }
//            case 2 -> {
//                sglCode = airProtocoBytes[1];
//            }
//            default -> {
//                log.debug("Unknown protocol type[{}]", protocolType);
//                return null;
//            }
//        }
//
//        TreeMap<Integer, FieldTemplate> templateTreeMap = SeekUtils.seekSignallingTemplate(protocolType, sglCode);
//        JSONObject jsonObject = parseToJSONObject(protocolType, sglCode, airProtocoBytes);
//        packagingResult(result, templateTreeMap, jsonObject);
//        return result;
//    }

//    private static void packagingResult(List<ParseResultEntity> result, TreeMap<Integer, FieldTemplate> templateTreeMap, JSONObject data)
//    {
//        Iterator<FieldTemplate> it = templateTreeMap.values().iterator();
//        while (it.hasNext())
//        {
//            ParseResultEntity entity = new ParseResultEntity();
//            FieldTemplate next = it.next();
//
//            String fieldName = next.getFieldName();
//            int length = next.getLength();
//            entity.setLength(length);
//            String name = MemStorage.propertyEntityMap.get(fieldName).getFieldDesc();
//            int type = MemStorage.propertyEntityMap.get(fieldName).getFieldType();
//            int tag = MemStorage.propertyEntityMap.get(fieldName).getFieldTag();
//            entity.setName(name);
//
//            switch (tag)
//            {
//                case 4 -> {
//                    JSONObject elongateJo = data.getJSONObject(fieldName);
//                    Integer len = elongateJo.getInteger("length");
//                    String hex = elongateJo.getString("hex");
//                    entity.setValue(len);
//                    result.add(entity);
//                    ParseResultEntity elongateEntity = new ParseResultEntity();
//                    elongateEntity.setLength(len);
//                    elongateEntity.setName(name.replace("长度", "内容"));
//                    elongateEntity.setValue(hex);
//                    result.add(elongateEntity);
//                }
//                default -> {
//                    TreeMap<Integer, FieldTemplate> subTemplateTreeMap = next.getTempleteTreeMap();
//                    if (null == subTemplateTreeMap)
//                    {
//                        if (type == 6)
//                        {
//                            entity.setValue(data.getJSONObject(fieldName).getString("stringValue"));
//                        }
//                        else if (type == 7)
//                        {
//                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//                            entity.setValue(sdf.format(data.getDate(fieldName)));
//                        }
//                        else
//                        {
//                            entity.setValue(ConversionUtils.convertValue(data.getString(fieldName), next.getFieldClass()));
//                        }
//                        result.add(entity);
//                        continue;
//                    }
//
//                    JSONArray jsonArray = data.getJSONArray(fieldName);
//                    entity.setValue(jsonArray.size());
//                    result.add(entity);
//                    for (int i = 0; i < jsonArray.size(); i++)
//                    {
//                        packagingResult(result, subTemplateTreeMap, jsonArray.getJSONObject(i));
//                    }
//                }
//            }
//        }
//    }

//    public static JSONObject parseToJSONObject(int protocolType, int sglCode, byte[] data) throws Exception
//    {
//        TreeMap<Integer, FieldTemplate> templateTreeMap = SeekUtils.seekSignallingTemplate(protocolType, sglCode);
//        TreeMap<String, Object> pareReuslt = ParseUtil.parse(data, templateTreeMap);
//        ObjectMapper objectMapper = new ObjectMapper();
//        return new ObjectMapper().convertValue(pareReuslt, JSONObject.class);
//    }

//    public static byte[] toByteArray(int protocolType, int sglCode, Object obj) throws Exception
//    {
//        TreeMap<Integer, TreeMap<Integer, FieldTemplate>> codeMap = MemStorage.signallingMap.get(protocolType);
//        if (null == codeMap)
//        {
//            throw new Exception("Protocol type isn't exists");
//        }
//
//        TreeMap<Integer, FieldTemplate> templateTreeMap = codeMap.get(sglCode);
//        if (null == templateTreeMap)
//        {
//            throw new Exception("Signalling code isn't exists");
//        }
//
//        return ParseUtil.toByteArray(obj, templateTreeMap);
//    }
}
